#include "OS/WindowEventUtils.h"

#include "Graphics/IRenderWindow.h"

namespace tyro
{
	namespace OS
	{
		WindowEventListeners WindowEventUtils::windowListeners;

		void WindowEventUtils::MessageHandler()
		{

#if TYRO_DEFINITION == TYRO_DEFINITION_WIN32
			MSG message;
			while( PeekMessage( &message, NULL, 0, 0, PM_NOREMOVE ))
			{
				GetMessage( &message, NULL, 0, 0 );
				TranslateMessage( &message );
				DispatchMessage( &message );
				if( message.message == WM_QUIT )
				{
					// Quit the application
				}
			}
#endif

		}

#if TYRO_DEFINITION == TYRO_DEFINITION_WIN32
		LRESULT WindowEventUtils::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
		{

			if (uMsg == WM_CREATE)
			{	// Store pointer to Win32Window in user data area
				SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
				return 0;
			}

			Graphics::IRenderWindow* win = (Graphics::IRenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);

			if (!win)
			{
				return DefWindowProc( hWnd, uMsg, wParam, lParam );
			}

			WindowEventListeners::iterator index,
				start = windowListeners.lower_bound(win),
				end = windowListeners.upper_bound(win);

			switch(uMsg)
			{
			case WM_SIZE:
				win->WindowMovedOrResized();
				break;
			case WM_CLOSE:

				for(index = windowListeners.lower_bound(win); index != end; ++index)
					(index->second)->WindowClosed(win);

				win->Release();
				break;
			}
			//TODO handle window events
			return DefWindowProc( hWnd, uMsg, wParam, lParam );
		}

		void WindowEventUtils::AddWindowEventListener( Graphics::IRenderWindow* window, WindowEventListener* listener )
		{
			windowListeners.insert(std::make_pair(window, listener));
		}

#endif

	}
}
